package com.bang.concurrency.example.singleton;

import com.bang.concurrency.annotations.NotRecommend;
import com.bang.concurrency.annotations.NotThreadSafe;
import com.bang.concurrency.annotations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Auther: Bang
 * @Date: 2019/9/30 21:16
 * @Description: 单例模式 懒汉式 双重检测机制
 *   instance=new SingletonExample3();
 *   1、memory = allocate() 分配对象的内存空间
 *   2、ctorInstance() 初始化对象
 *   3、instance = memory 设置instance指向刚分配的内存
 *
 *   JVM和cpu优化，发生了指令重排
 *
 *   1、memory = allocate() 分配对象的内存空间
 *   3、instance = memory 设置instance指向刚分配的内存
 *   2、ctorInstance() 初始化对象
 */
@NotThreadSafe
@Slf4j
@NotRecommend
public class SingletonExample3 {

    // 私有化构造方法
    private SingletonExample3() {
    }

    private static SingletonExample3 instance = null;

    // 静态的工厂方法
    public static SingletonExample3 getInstance() {
        if (null == instance) {
            synchronized (SingletonExample3.class) {
                if (null == instance) {
                    instance = new SingletonExample3();
                }
            }
        }
        return instance;
    }

    public static void main(String[] args) {
        ExecutorService service = Executors.newCachedThreadPool();
        Set<SingletonExample3> set = new CopyOnWriteArraySet<>();
        for (int i = 0; i < 500; i++) {
            service.execute(() -> {
                SingletonExample3 instance = SingletonExample3.getInstance();
                set.add(instance);
            });
        }
        service.shutdown();
        System.err.println(set.size());
    }


}
